<template>
  <div ref="mapRef">aaa
<!--      <div class="row justify-center" :class="qInstace.fullscreen.isActive? '' : 'hidden'" style="position:absolute;left:40vw;height:10vh;z-index: 1000;width: 20vw;background: #ccd1d7;">-->
<!--          <q-input bottom-slots v-model="searchValue" label="搜索位置或坐标...." style="">-->
<!--            <template v-slot:before>-->
<!--              <q-icon name="explore" color="light-blue"/>-->
<!--            </template>-->
<!--            <template v-slot:append>-->
<!--              <q-btn round dense flat icon="search" color="light-blue" @click="submit" />-->
<!--            </template>-->
<!--          </q-input>-->
<!--          <div class="text-center">{{Geo.position.toString()}}</div>-->
<!--      </div>-->
      <div id="mapDiv" style="width: 100vw;height: 100vh;" >
      </div>
      <div  style="z-index: 2000;">
        <q-btn color="primary" @click="loadMap">点击加载</q-btn>
      </div>
    <q-btn
      color="secondary"
      @click="loadMap"
      :icon="qInstace.fullscreen.isActive ? 'fullscreen_exit' : 'fullscreen'"
      :size="qInstace.fullscreen.isActive ? '20px' : '8px'"
      style="position: absolute; bottom: 8px; right: 15px; z-index: 100000"
    />
  </div>
</template>

<script>
// 地图组件
import { onMounted, defineComponent, ref, reactive } from 'vue'
import { useQuasar } from 'quasar'

export default defineComponent({
  name: 'MapComponent',
  props: {
    position: { // 从父组件传来的搜索字符
      type: Array,
      default: function () {
        return []
      }
    }
  },
  setup (props, context) {
    let map = ref(null)
    let marker = null
    const mapSize = reactive({ width: '20px', height: '20px' })
    const mapShow = ref(false)
    const searchValue = ref('')
    let script = null
    // const distinction = ''
    const Geo = reactive({ // 保存选定的地方的坐标信息
      position: [], // 保存地理坐标
      degree: [] // 保存度分秒坐标
    })
    const qInstace = useQuasar()
    onMounted(() => {
      initMap()
    })
    const initMap = () => {
      // let script = document.getElementById('MapDivId')
      // if (script) {
      //   return _initMap()
      // }
      script = document.createElement('script')
      script.id = 'MapDivId'
      script.src = 'https://api.tianditu.gov.cn/api?v=4.0&tk=001ef366a77a0f4fb4d8d89f8d72094d' // 天地图地址
      document.body.appendChild(script) // 添加节点
      console.log('ddd')
      script.onload = function () { // 加载节点时的回调
        _initMap()
      }
    }
    const _initMap = () => {
      // eslint-disable-next-line no-undef
      map.value = new T.Map('mapDiv')
      // let lng = 120.177832
      // let lat = 30.2462
      // if (props.position) {
      //   lng = props.position[0]
      //   lat = props.position[1]
      // }
      console.log(props.position)
      // eslint-disable-next-line no-undef
      map.value.centerAndZoom(new T.LngLat(120.177832, 30.2462), 12)
      // 添加卫星图层，下面这个url是固定的
      map.value.on('click', (e) => { // 点击添加标志事件
        console.log(e)
        const lnglat = e.lnglat
        marker = null // 重置标记对象
        map.value.clearOverLays() // 清除地图上所有覆盖物

        // eslint-disable-next-line no-undef
        marker = new T.Marker(lnglat) // 创建标志
        calculate(lnglat, 0)
        map.value.addOverLay(marker) // 添加标志

        const zoom = map.value.getZoom() // 获取当前缩放级别
        map.value.panTo(lnglat, zoom) // 调整中心点和缩放级别
      })
      // //添加地图类型控件
      // eslint-disable-next-line no-undef
      const ctrlMapType = new T.Control.MapType([
        {
          title: '卫星混合',
          icon: 'http://api.tianditu.gov.cn/v4.0/image/map/maptype/satellitepoi.png',
          // eslint-disable-next-line no-undef
          layer: TMAP_HYBRID_MAP
        },
        {
          title: '地图',
          icon: 'http://api.tianditu.gov.cn/v4.0/image/map/maptype/vector.png',
          // eslint-disable-next-line no-undef
          layer: TMAP_NORMAL_MAP
        }
      ])
      map.value.addControl(ctrlMapType)
      // console.log('aaa')
    }
    const search = (value) => {
      // 值不为空
      if (value) {
        // eslint-disable-next-line no-unused-vars
        let position = Geo.position
        // eslint-disable-next-line no-unused-vars
        let degree = Geo.degree
        let localsearch = null
        // 添加搜索
        const config = {
          pageCapacity: 10, // 每页显示的数量
          onSearchComplete: localSearchResult // 接收数据的回调
        }
        // 创建搜索
        // eslint-disable-next-line no-undef
        localsearch = new T.LocalSearch(map, config)

        localsearch.search(value, 7) // 设定搜索值和搜索类型

        // 搜索完成回调
        function localSearchResult (result) {
          console.log(result)
          const posiStr = result.pois[0].lonlat // 坐标字符串

          const posiArr = [] // 坐标数组
          console.log(posiStr)
          // 将字符串转为数字存到数组中
          const a = posiStr.split(' ')

          a.forEach((item, index) => {
            const tem = Number(item)
            posiArr.push(tem)
          })
          console.log(posiArr)
          position = posiArr // 保存坐标
          degree = calculate(posiArr, 0) // 保存坐标

          context.emit('sendPosi', Geo) // 发送事件

          marker = null // 重置标记对象
          map.value.clearOverLays() // 清除地图上所有覆盖物
          // eslint-disable-next-line no-undef
          const lnglat = new T.LngLat(posiArr[0], posiArr[1])
          // eslint-disable-next-line no-undef
          marker = new T.Marker(lnglat) // 创建标志
          map.value.addOverLay(marker) // 添加标志

          // map.setViewport(120.2042181, 30.24775551) // 调整视野,没用?
          const zoom = map.value.getZoom() // 获取当前缩放级别
          map.value.panTo(lnglat, zoom) // 调整中心点和缩放级别
        }
      }
    }
    const submit = () => {
      // 判断输入类型
      if (typeof (searchValue.value) === 'string') { // 字符串
        console.log(searchValue.value)
        if (searchValue.value.indexOf(',') === -1) { // 输入纯字符串
          search(searchValue.value)
        } else if (searchValue.value.indexOf('°') !== (-1)) { // 含有度数符号,为度数字符串
          const a = searchValue.value.split(',')
          calculate(a, 1)
        } else { // 处理纯数字字符串
          const a = searchValue.value.split(',')
          const temp = a.map((item) => { // 转为数字
            return Number(item.trim())
          })
          calculate(temp, 0)
        }
      } else if (searchValue.value instanceof Array) { // 数组
        if (searchValue.value[0].toString().indexOf('°') !== -1) { // 第一个元素含有度符号
          calculate(searchValue.value, 1)
        } else {
          calculate(searchValue.value, 0)
        }
      } else {
        console.log('传入参数类型错误,请传入字符串或坐标数组!')
      }
    }
    const mapRef = ref(null)
    const loadMap = () => {
      if (qInstace.fullscreen.isActive) {
        mapShow.value = false
        const target = mapRef.value
        qInstace.fullscreen.toggle(target)
      } else {
        mapShow.value = true
        const target = mapRef.value
        qInstace.fullscreen.toggle(target)
      }
    }
    const createMarker = (posiObj) => { // 创建由传递参数所需创建的标记
      console.log(posiObj)
      marker = null // 重置标记对象
      map.value.clearOverLays() // 清除地图上所有覆盖物
      // eslint-disable-next-line no-undef
      marker = new T.Marker(posiObj) // 创建标志
      map.value.addOverLay(marker) // 添加标志
      const zoom = map.value.getZoom() // 获取当前缩放级别
      map.value.panTo(posiObj, zoom) // 调整中心点和缩放级别
    }
    const calculate = (param, num) => { // 计算度分秒坐标
      let temp // 临时数组,保存坐标
      let result // 保存及计算的坐标数组

      switch (num) {
        case 0 : // 参数为0,由经纬度计算度分秒坐标
          if (!param.length) { // 参数是对象
            console.log(param)
            temp = [param.lng, param.lat] // 临时数组
            Geo.position = temp // 保存坐标数组
            result = calculateGeo(temp) // 计算度分秒坐标
            Geo.degree = result // 保存坐标
            context.emit('sendPosi', Geo) // 发送事件
            console.log(Geo)
          } else if (param instanceof Array) { // 参数是数组
            temp = param
            console.log(param)
            Geo.position = temp
            result = calculateGeo(param)
            Geo.degree = result
            context.emit('sendPosi', Geo) // 发送事件
            createMarker({ lon: param[0], lat: param[1] }) // 传递的数组创建的标记
            // console.log(this.Geo)
          } else {
            console.log('参数类型错误!')
          }
          break
        case 1: // 参数为1,由度分秒计算经纬度坐标

          // 由度分秒数组绘制标记
          result = calculateDegree(param) // 转化好的经纬度数组
          createMarker({ lng: result[0], lat: result[1] })
          Geo.position = result
          Geo.degree = param
          context.emit('sendPosi', Geo) // 发送事件
          break
      }

      function calculateGeo (lonlatArr) { // 经纬度转为度分秒
        // 示例: lonlatArr=[116.41661560068297, 39.92196580126834]
        console.log(lonlatArr)
        const result = []
        lonlatArr.forEach((item) => {
          const str = item.toString()
          const int = str.split('.')[0] // 获取整数部分
          const decimal1 = '0.' + str.split('.')[1] // 获取第一个小数部分
          const num = (Number(decimal1) * 60).toFixed(6) // 获取分钟数和小数
          const minute = Math.floor(Number(num)) // 获取分钟
          const decimal2 = '0.' + num.toString().split('.')[1] // 获取第二个小数
          const second = (Number(decimal2) * 60).toFixed(3) // 获取秒
          const resStr = int + '°' + minute.toString() + '\'' + second.toString() + '"'
          result.push(resStr)
        })
        // console.log(result)
        return result
      }

      function calculateDegree (degreeArr) { // 度分秒转经纬度
        console.log(degreeArr)
        // 示例: degreeArr=['114°65\'24.6','57°55\'56.6']
        const result = []
        degreeArr.forEach((item) => {
          const str = item.toString()
          const degree = str.split('°')[0]// 度
          const minute = str.split('\'')[0].split('°')[1] // 分
          const length = str.split('\'')[1].length // 秒的长度
          const second = str.split('\'')[1].substring(0, length - 1) // 截取到秒
          const res = (Number(degree) + Number(minute) / 60 + Number(second) / 3600).toFixed(6) // 相加获取最终坐标

          result.push(res)
        })
        return result
      }
      return result
    }
    const mapExit = () => {
      map = null
      script.remove()
      context.emit('exit')
    }
    return {
      searchValue,
      mapExit,
      search,
      Geo,
      qInstace,
      mapRef,
      submit,
      mapSize,
      mapShow,
      loadMap
    }
  }
}
)
</script>

<style scoped>

</style>
